#include "guiterm.hpp"
#include <string.h>
#include <QMenuBar>
#include <QMessageBox>
#include <QShortcut>

TerminalWindow::TerminalWindow()
{
	resize(640, 480);
	
	this->currentTab = NULL;
	this->previousTab = NULL;
	
	setupLayout();
	setupActions();
	setupMenus();
}

TerminalWindow::~TerminalWindow()
{
	delete tabs;
	delete fileMenu;
		delete exitAct;
	delete tabMenu;
	delete helpMenu;
		delete helpAboutAct;
}

void TerminalWindow::addTab(Tab *tab)
{
	tab->setWindow(this);
	int index = tabs->count();
	
	// Look for a gap between tab numbers to insert the new tab into
	for(int ii=0; ii<tabs->count(); ii++) {
		if( ((Tab*)tabs->widget(ii))->getIndex() > ii ) {
			index = ii;
			break;
		}
	}
	
	tab->setIndex(index);
	string label = tab->getLabel();
	index = tabs->insertTab(index, tab, label.c_str());
	
	tabs->setCurrentIndex(index);
}

void TerminalWindow::removeTab(Tab *tab)
{
	int index = tabs->indexOf(tab);
	tabs->removeTab(index);
	
	if(currentTab == tab) currentTab = NULL;
	else if(previousTab == tab) previousTab = NULL;
	
	// When the last tab closes, close the window
	if(!tabs->count())
		close();
}

Tab *TerminalWindow::getCurrentTab()
{
	return (Tab*)tabs->currentWidget();
}

vector<Tab*> TerminalWindow::getTabs()
{
	vector<Tab*> ret;
	for(int ii=0; ii<tabs->count(); ii++)
	{
		ret.push_back((Tab*)tabs->widget(ii));
	}
	return ret;
}

void TerminalWindow::tabNameChanged(Tab *tab)
{
	int index = tabs->indexOf(tab);
	if(index >= 0)
		tabs->setTabText(index, tab->getLabel().c_str());
}

void TerminalWindow::giveFocus()
{
	Tab *tab = getCurrentTab();
	if(!tab) return;
	Session *session = tab->getSession();
	if(!session) return;
	
	session->giveFocus();
}

void TerminalWindow::setupLayout()
{
	setFocusPolicy(Qt::NoFocus);
	
	tabs = new QTabWidget();
#if QT_VERSION >= 0x040500
	tabs->setDocumentMode(true);
#endif
	tabs->setTabPosition(QTabWidget::South);
	tabs->setFocusPolicy(Qt::NoFocus);
	setCentralWidget(tabs);
	
	connect(tabs, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int)));
}

void TerminalWindow::setupActions()
{
	exitAct = new QAction(tr("E&xit"), this);
	exitAct->setStatusTip("Close this window");
	connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
	
	helpAboutAct = new QAction(tr("&About"), this);
	connect(helpAboutAct, SIGNAL(triggered()), this, SLOT(helpAbout()));
}

void TerminalWindow::setupMenus()
{
	fileMenu = menuBar()->addMenu("File");
	fileMenu->addAction(exitAct);
	
	tabMenu = new TabMenu(this);
	menuBar()->addMenu(tabMenu);
	
	helpMenu = menuBar()->addMenu("Help");
	helpMenu->addAction(helpAboutAct);
}

bool TerminalWindow::globalHotkey(QKeyEvent *event)
{
	if(event->key() == 'A' && event->modifiers() == Qt::ControlModifier)
	{
		// ^A opens the t(a)bs menu
		// We have to handle it here because normally, the line editor has &A as a
		// shortcut for 'select all'.
		openTabMenu();
		event->accept();
		return true;
	}
	else
	{
		return false;
	}
}

void TerminalWindow::keyPressEvent(QKeyEvent *event)
{
	// Don't tab between widgets (because tab is used for completion instead)
	if(globalHotkey(event))
		return;
	if(event->key() == Qt::Key_Tab)
		event->ignore();
	else
		QWidget::keyPressEvent(event);
}

void TerminalWindow::openTabMenu()
{
	menuBar()->setActiveAction(tabMenu->menuAction());
}

void TerminalWindow::createTab()
{
	BackendConnection *backend = new BackendConnection();
	ServerConnection *connection = backend->getFirstHost();
	Session *session = new Session(connection);
	
	addTab(session->getTab());
	
	session->begin();
}

void TerminalWindow::nextTab()
{
	int index = tabs->currentIndex();
	if(index+1 >= tabs->count())
		tabs->setCurrentIndex(0);
	else
		tabs->setCurrentIndex(index+1);
}

void TerminalWindow::prevTab()
{
	int index = tabs->currentIndex();
	if(index == 0)
		tabs->setCurrentIndex(tabs->count()-1);
	else
		tabs->setCurrentIndex(index-1);
}

void TerminalWindow::lastTab()
{
	Tab *currentTab = (Tab*)tabs->currentWidget();
	
	if(previousTab && previousTab != currentTab) {
		int index = tabs->indexOf(previousTab);
		if(index >= 0) {
			tabs->setCurrentIndex(index);
			return;
		}
	}
	nextTab();
}

void TerminalWindow::changeTab(int index)
{
	tabs->setCurrentIndex(index);
}

void TerminalWindow::tabChanged(int index)
{
	Tab *newTab = (Tab*)tabs->widget(index);
	if(newTab) {
		previousTab = currentTab;
		currentTab = newTab;
	}
	
	if(tabs->isVisible())
		giveFocus();
}

void TerminalWindow::helpAbout()
{
	QMessageBox aboutBox;
		aboutBox.setWindowTitle("About Guiterm");
		aboutBox.setText(GUITERM_VERSION_STRING);
	aboutBox.exec();
}

